import { Injectable } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import * as qs from 'qs';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class RestService {

  constructor(
    private http: HttpClient,
  ) { }

  heroes = [0, 1, 2, 3, 4];

  private heroesUrl = 'api/heroes';  // URL to web api

  // feed
  private apiUrlFeeds = 'https://imoocqa.gugujiankong.com/api/feeds/get';

  // account
  private apiUrlRegister = 'https://imoocqa.gugujiankong.com/api/account/register';
  private apiUrlLogin = 'https://imoocqa.gugujiankong.com/api/account/login';
  private apiUrlUserInfo = 'https://imoocqa.gugujiankong.com/api/account/userinfo';
  private apiUrlUpdateNickName = 'https://imoocqa.gugujiankong.com/api/account/update';

  // question
  private apiUrlQuestionSave = 'https://imoocqa.gugujiankong.com/api/question/save';
  private apiUrlQuestionLIst = 'https://imoocqa.gugujiankong.com/api/question/list?';
  private apiUrlGetQuestion = 'https://imoocqa.gugujiankong.com/api/question/get';
  private apiUrlAnswer = 'https://imoocqa.gugujiankong.com/api/question/answer';

  /**
   * 根据用户手机号码和密码进行登陆
   *
   * @param {*} mobile
   * @param {*} password
   * @returns {Observable<string[]>}
   * @memberof RestService
   */
  login(mobile, password): Observable<string> {
    return this.getUrlReturn(this.apiUrlLogin + '?mobile=' + mobile + '&password=' + password);
  }

  /**
   * 该课程不涉及安全性方面考虑 ，所以不加密。
   *
   * @param {*} mobile
   * @param {*} nickname
   * @param {*} password
   * @returns {Observable<string>}
   * @memberof RestService
   */
  register(mobile, nickname, password): Observable<string> {
    return this.getUrlReturn(this.apiUrlRegister + '?mobile=' + mobile + '&nickname=' + nickname + '&password=' + password);
  }

  // 需要在app.module.ts中引入HttpClientModule,不然会报错
  // 全局获取HTTP请求的方法
  private getUrlReturn(url: string): Observable<string> {
    return this.http.get<string>(url)
      .pipe(
        // HttpClient.get 返回响应数据,不常用
        // map(res => res),
        // 查看 Observable 中的值.这种 tap 回调不会改变这些值本身。
        // 示例：tap(_ => this.log('get urls yet')),
        tap(this.extractData),
        // 错误处理
        catchError(this.handleError<string>('getUrl', ''))
      );

  }

  private extractData(res) {
    const data = JSON.parse(res) || {};
    return data;
  }

  // catchError() 操作符会拦截失败的 Observable。 它把错误对象传给错误处理器，错误处理器会处理这个错误。
  // 下面的 handleError() 方法会报告这个错误，并返回一个无害的结果（安全值），以便应用能正常工作。
  /**
   * Handle Http operation that failed.
   * Let the app continue.
   * @param operation - name of the operation that failed
   * @param result - optional value to return as the observable result
   */
  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      // TODO: better job of transforming error for user consumption
      this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

  /** Log a HeroService message with the MessageService */
  private log(message: string) {
    // this.messageService.add(`HeroService: ${message}`);
    console.log('错误信息：' + message);
  }

}
